#!/usr/bin/perl
use strict;
use warnings;

use lib '../lib';
use lib '../extlib';
use ChessLike::Board;
use ChessLike::BoardUtils;

use Test::Exception;
use Test::More 'no_plan';

# Create a brand new gameboard with custom dimensions
my $board = ChessLike::Board->new( 'x-tiles' => 3, 'y-tiles' => 4 );

# Populate the board with game pieces
my $pawn1 = ChessLike::GamePiece->new();
$board->add(
   'a2',
   'gamepiece' => $pawn1,
   'direction' => 'n',
   'team'      => 0,
   'graphic'   => 'pawn-white',
);

my $flying_pawn1 = ChessLike::GamePiece->new( 'is-flying' => 1, );
$board->add(
   'b2',
   'gamepiece' => $flying_pawn1,
   'direction' => 'w',
   'team'      => 0,
   'graphic'   => 'flying-pawn-white',
);

my $flying_pawn2 = ChessLike::GamePiece->new( 'is-flying' => 1, );
$board->add(
   'b2',
   'gamepiece' => $flying_pawn2,
   'direction' => 'e',
   'team'      => 0,
   'graphic'   => 'flying-pawn-white',
);

my $pawn2 = ChessLike::GamePiece->new();
$board->add(
   'b2',
   'gamepiece' => $pawn2,
   'direction' => 'n',
   'team'      => 0,
   'graphic'   => 'pawn-white',
);

my $pawn3 = ChessLike::GamePiece->new();
$board->add(
   'c4',
   'gamepiece' => $pawn3,
   'direction' => 's',
   'team'      => 1,
   'graphic'   => 'pawn-black',
);

my $flying_pawn3 = ChessLike::GamePiece->new( 'is-flying' => 1, );
$board->add(
   'c4',
   'gamepiece' => $flying_pawn3,
   'direction' => 's',
   'team'      => 1,
   'graphic'   => 'flying-pawn-black',
);

## a2: Pawn-1
## b2: Pawn-2, Flying-Pawn-1, Flying_Pawn-2
## c4: Pawn-3, Flying-Pawn-3

# Try to create iterator without an instance of ChessLike::Board
dies_ok { my $iterator = find_tile_contents( "Can't touch this!" ) }
   '[find_tile_contents] checking error when ChessLike::Board not provided';

# Create iterator
my $iterator = find_tile_contents( $board );
is( ref $iterator, 'CODE', '[find_tile_contents] ref' );

# Find first game piece
my @contents = next_tile_contents( $iterator, 'gamepiece', 'direction',
   'team', 'graphic', );
is( @contents,      6, '[next_tile_contents 1] return value: size' );
is( $contents[0], 'a2',   '[next_tile_contents 1] return value: tile' );
is( $contents[1], 0,      '[next_tile_contents 1] return value: index' );
is( $contents[2], $pawn1, '[next_tile_contents 1] return value: gamepiece' );
is( $contents[3], 'n',    '[next_tile_contents 1] return value: direction' );
is( $contents[4], 0,      '[next_tile_contents 1] return value: team' );
is( $contents[5], 'pawn-white',
   '[next_tile_contents 1] return value: graphic' );

# Find next game piece, while switching the order of returned values
@contents = next_tile_contents( $iterator, 'team', 'graphic',
   'gamepiece', 'direction', );
is( @contents,      6, '[next_tile_contents 2] return value: size' );
is( $contents[0],  'b2',   '[next_tile_contents 2] return value: tile' );
is( $contents[1],  0,      '[next_tile_contents 2] return value: index' );
is( $contents[2],  0,      '[next_tile_contents 2] return value: team' );
is( $contents[3], 'pawn-white',
   '[next_tile_contents 2] return value: graphic' );
is( $contents[4], $pawn2, '[next_tile_contents 2] return value: gamepiece' );
is( $contents[5], 'n',    '[next_tile_contents 2] return value: direction' );

# Find next game piece, without specifying return values
@contents = next_tile_contents( $iterator );
is( @contents,      2, '[next_tile_contents 3] return value: size' );
is( $contents[0], 'b2',   '[next_tile_contents 3] return value: tile' );
is( $contents[1], 1,      '[next_tile_contents 3] return value: index' );

# Find next game piece, specifying only two return values
@contents = next_tile_contents( $iterator, 'direction', 'gamepiece', );
is( @contents,      4, '[next_tile_contents 4] return value: size' );
is( $contents[0], 'b2',   '[next_tile_contents 4] return value: tile' );
is( $contents[1], 2,      '[next_tile_contents 4] return value: index' );
is( $contents[2], 'e',    '[next_tile_contents 4] return value: direction' );
is( $contents[3], $flying_pawn2,
   '[next_tile_contents 4] return value: gamepiece' );

# Find next game piece, specifying only one return value
@contents = next_tile_contents( $iterator, 'graphic', );
is( @contents,      3, '[next_tile_contents 5] return value: size' );
is( $contents[0], 'c4',   '[next_tile_contents 5] return value: tile' );
is( $contents[1], 0,      '[next_tile_contents 1] return value: index' );
is( $contents[2], 'pawn-black',
   '[next_tile_contents 5] return value: graphic' );

# Find next game piece, specifying all return values
@contents = next_tile_contents( $iterator, 'gamepiece', 'direction',
   'team', 'graphic', );
is( @contents,      6, '[next_tile_contents 6] return value: size' );
is( $contents[0], 'c4',   '[next_tile_contents 6] return value: tile' );
is( $contents[1], 1,      '[next_tile_contents 6] return value: index' );
is( $contents[2], $flying_pawn3, '[next_tile_contents 6] return value: gamepiece' );
is( $contents[3], 's',    '[next_tile_contents 6] return value: direction' );
is( $contents[4], 1,      '[next_tile_contents 6] return value: team' );
is( $contents[5], 'flying-pawn-black',
   '[next_tile_contents 6] return value: graphic' );

# Discover exhausted iterator
is( next_tile_contents( $iterator, 'gamepiece', 'direction', 'graphic', ),
   undef, '[next_tile_contents] iterator exhausted' );

